/*
 * Copyright (c) 2008, Xiong Yingfei, the University of Tokyo All rights
 * reserved.
 */
package ac.jp.u_tokyo.SyncLib;

import java.util.List;

import static ac.jp.u_tokyo.SyncLib.util.Helper.*;

public class IDSync extends StatelessSync
{
	boolean _v1OverV2;

	public IDSync(boolean Param1OverParam2)
	{
		super();
		_v1OverV2 = Param1OverParam2;
	}


	public int getParaCount()
	{
		return 2;
	}

	public static Mod mergeWithValue(Mod tgtmod, Mod srcmod, Object tgtv,
			Object srcv) throws SynchronizationFailedException
	{
		if (conflict(tgtmod, srcmod))
			throw new SynchronizationFailedException();
		Mod allMods = merge(tgtmod, srcmod);

		Mod inverseTgtv = getInverse(allMods, tgtv);
		tgtv = inPlaceApply(allMods, tgtv);
		try
		{
			Mod v2tov1Mod = Value2Mod.findMod(srcv, tgtv);

			assert !conflict(v2tov1Mod, allMods) : "Founded mod: "
					+ v2tov1Mod.toString() + " Merged mod:" + allMods;

			allMods = merge(allMods, v2tov1Mod);
			return allMods;
		}
		finally
		{
			inPlaceApply(inverseTgtv, tgtv);
		}
	}

	public static Mod mergeWithValue(Mod mod1, Mod mod2, Object v1, Object v2,
			boolean v1overv2) throws SynchronizationFailedException
	{
		if (v1overv2)
			return mergeWithValue(mod1, mod2, v1, v2);
		else
			return mergeWithValue(mod2, mod1, v2, v1);
	}


//	public Object[] getInitialValues()
//	{
//		return new Object[] { _initialValue, _initialValue };
//	}

	public Mod[] resynchronize(Object[] values, Mod[] modifications)
			throws SynchronizationFailedException
	{
		Mod mod1 = modifications[0];
		Mod mod2 = modifications[1];
		Object v1 = values[0];
		Object v2 = values[1];

		Mod result;
		result = mergeWithValue(mod1, mod2, v1, v2, _v1OverV2);

		return new Mod[] { result, result };
	}

	public Mod[] synchronize(Mod[] modifications)
			throws SynchronizationFailedException
	{
		Mod mod1 = modifications[0];
		Mod mod2 = modifications[1];

		if (conflict(mod1, mod2)) throw new SynchronizationFailedException();

		Mod result = merge(mod1, mod2);
		return new Mod[] { result, result };
	}

}
